#include <string.h>
#include <stdio.h>
#include <rid.h>

#include "rid_hex.h"

void
rid_hex(char *str, const Rid id)
{
	/* uses bytes so we don't need to worry about endianness */
	for (size_t i = 0; i < sizeof(Rid); ++i, str += 2)
		sprintf(str, "%02hhx", id[i]);
}

static inline unsigned char
hex_to_val(unsigned char c)
{
	/* all unassigned values are 0, so '0' must be set to something else */
	static const unsigned char table[256] = {
		['0'] = 1, ['1'] = 2, ['2'] = 3, ['3'] = 4, ['4'] = 5,
		['5'] = 6, ['6'] = 7, ['7'] = 8, ['8'] = 9, ['9'] = 10,
		['a'] = 11, ['b'] = 12, ['c'] = 13, ['d'] = 14, ['e'] = 15,
		['f'] = 16
	};

        return table[c];
}

int
rid_hex_parse(Rid id, const char *str)
{
	for (size_t i = 0; i < sizeof(Rid); ++i) {
		unsigned char c1, c2;

		if (!(c1 = hex_to_val(*str++)))
			return i * 2;

		if (!(c2 = hex_to_val(*str++)))
			return i * 2 + 1;

		/* put together the who halfs of the byte */
		id[i] = (c1 - 1) << 4 | (c2 - 1);
	}

	return RID_HEX_LEN;
}

void
rid_hex_path(char *path, const Rid id)
{
	sprintf(path, "%02hhx/", id[0]);
	path += 3;

	for (size_t i = 1; i < sizeof(Rid); ++i, path += 2)
		sprintf(path, "%02hhx", id[i]);
}
